using Aurora.EventBus.Builders;
using Aurora.EventBus.Dependencies;
using Aurora.EventBus.Factories;
using Aurora.EventBus.HostedServices;
using Aurora.EventBus.Internal;
using Aurora.EventBus.Storage;
using Microsoft.Extensions.DependencyInjection;

namespace Aurora.EventBus.Extensions;

/// <summary>
/// Aurora.EventBus 模块服务拓展
/// </summary>
public static class EventBusServiceCollectionExtensions
{
    /// <summary>
    /// 添加 Aurora.EventBus 模块注册
    /// </summary>
    /// <param name="services">服务集合对象</param>
    /// <param name="configureOptionsBuilder">事件总线配置选项构建器委托</param>
    /// <returns>服务集合实例</returns>
    public static IServiceCollection AddEventBus(this IServiceCollection services, Action<EventBusOptionsBuilder> configureOptionsBuilder)
    {
        // 创建初始事件总线配置选项构建器
        var eventBusOptionsBuilder = new EventBusOptionsBuilder();
        configureOptionsBuilder.Invoke(eventBusOptionsBuilder);
        return services.AddEventBus(eventBusOptionsBuilder);
    }
    
    
    
    /// <summary>
    /// 添加 Aurora.EventBus 模块注册
    /// </summary>
    /// <param name="services">服务集合对象</param>
    /// <param name="builder">事件总线配置选项构建器</param>
    /// <returns>服务集合实例</returns>
    public static IServiceCollection AddEventBus(this IServiceCollection services, EventBusOptionsBuilder builder)
    {
        builder ??= new EventBusOptionsBuilder();

        // 注册内部服务
        services.AddInternalService(builder);

        // 构建事件总线服务
        builder.Build(services);


        services.AddHostedService(serviceProvider =>
        {
            // 创建事件总线后台服务
            var eventBusHostedService = ActivatorUtilities.CreateInstance<EventBusHostedService>(
                serviceProvider, builder.UseUtcTimestamp, builder.FuzzyMatch, builder.GCCollect,
                builder.LogEnabled);

            var unobservedTaskExceptionHandler = builder.UnobservedTaskExceptionHandler;
            if (unobservedTaskExceptionHandler != default)
            {
                eventBusHostedService.UnobservedTaskException += unobservedTaskExceptionHandler;
            }

            return eventBusHostedService;
        });

        return services;
    }


    private static IServiceCollection AddInternalService(this IServiceCollection services,
        EventBusOptionsBuilder builder)
    {
        // var defaultStorageChannel = new ChannelEventSourceStorage(builder.ChannelCapacity);

        services.AddSingleton<IEventSourceStorage>(_ => new ChannelEventSourceStorage(builder.ChannelCapacity));
        // 注册默认内存通道事件发布者
        services.AddSingleton<IEventPublisher, ChannelEventPublisher>();
        // 注册事件总线工厂
        services.AddSingleton<IEventBusFactory, EventBusFactory>();
        return services;
    }
}